package com.zoe.onelink.business.param.impl.dict.impl;

import com.zoe.onelink.business.cache.bean.IParamEntity;
import com.zoe.onelink.business.cache.bean.SysParamCustom;
import com.zoe.onelink.business.constant.CacheConst;
import com.zoe.onelink.business.constant.RequestConst;
import com.zoe.onelink.business.param.impl.dict.DictBizParamResolver;
import com.zoe.onelink.util.OnelinkContextHolder;
import com.zoe.onelink.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2022</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2022-10-28
 */
@Slf4j
public class LocalDictBizParamResolver implements DictBizParamResolver {


    private final Map<String, List<SysParamCustom>> cacheMap = new ConcurrentHashMap<>();

    private final Map<String, Integer> paramClassNameSeqMap = Map.of(
            CacheConst.USER_PARAMS_NAME, 1,
            CacheConst.DEPT_PARAMS_NAME, 2,
            CacheConst.DISTRICT_PARAMS_NAME, 3,
            CacheConst.GLOBAL_PARAMS_NAME, 10
    );

    @Override
    public IParamEntity resolve(String paramName) {
        List<SysParamCustom> sortedParams = this.cacheMap.get(paramName);
        if (sortedParams == null || sortedParams.isEmpty()) {
            return null;
        }
        return sortedParams.stream()
                // 参数获取优先级: 个人参数 -> 科室参数 -> 院区参数 -> 全局参数
                .filter(param -> this.isMatch(param, CacheConst.USER_PARAMS_NAME, OnelinkContextHolder.getString(RequestConst.HEADER_OPERATOR))
                        || this.isMatch(param, CacheConst.DEPT_PARAMS_NAME, OnelinkContextHolder.getString(RequestConst.HEADER_DEPT_CODE))
                        || this.isMatch(param, CacheConst.DISTRICT_PARAMS_NAME, OnelinkContextHolder.getString(RequestConst.HEADER_DISTRICT_CODE))
                        || CacheConst.GLOBAL_PARAMS_NAME.equals(param.getCustomParamClassName())
                )// 只取第一个即可
                .findFirst().orElse(null);
    }

    private boolean isMatch(SysParamCustom param, String className, String classValue) {
        return className.equals(param.getCustomParamClassName()) && StrUtil.equals(classValue, param.getCustomParamClassValue());
    }

    public synchronized void refreshCache(List<SysParamCustom> params) {
        if (params == null || params.isEmpty()) {
            log.warn("[OneLinkFrm] [本地字典缓存更新] 要更新的字典列表为空");
            return;
        }
        long paramSize = this.cacheMap.values().stream().mapToLong(Collection::size).sum();
        log.info("[OneLinkFrm] [本地字典缓存更新] 更新前数量:{},准备更新的数量:{}", paramSize, params.size());
        Map<String, List<SysParamCustom>> updatedParamMap = params.stream()
                .collect(Collectors.groupingBy(SysParamCustom::getParamName));
        for (Map.Entry<String, List<SysParamCustom>> entry : updatedParamMap.entrySet()) {
            String key = entry.getKey();
            if (!this.cacheMap.containsKey(key)) {
                log.info("[OneLinkFrm] [本地字典缓存更新] 移除字典 [{}]", key);
                this.cacheMap.remove(key);
                continue;
            }
            List<SysParamCustom> updatedParams = entry.getValue();
            updatedParams.sort(Comparator.comparingInt(param -> paramClassNameSeqMap.getOrDefault(param.getCustomParamClassName(), 20)));
            this.cacheMap.put(key, updatedParams);
            log.info("[OneLinkFrm] [本地字典缓存更新] 更新完成");
        }
    }

}
